#!/usr/bin/env python
# -*- coding:utf-8 -*-
import binascii
import os,sys
import traceback
from conf.setting import SPLITF_PATH
from libs import printer
import re

DFILE = SPLITF_PATH
MFILES = {}
def file_split(sfp,size):
    sfile = open(sfp,"rb")
    i = 0
    while True:
        c = sfile.read(size)
        if c:
            pfile = os.path.join(DFILE,('sfile%04d'%(i+1)))
            print(pfile)
            tfile = open(pfile,'wb')
            tfile.write(c)
            tfile.close()
        else:
            break
        i += 1
def mem_split(sfp,size):
    sfile = open(sfp,"rb")
    i = 0
    result = {}
    while True:
        c = sfile.read(size)
        if c:
            result['s%04d'%(i+1)] = c
        else:
            break
        i += 1
    return result

def show_mem_files(sfp,size):
    global MFILES
    MFILES = mem_split(sfp,size)
    if MFILES:
        for f in MFILES.keys():
            printer.plus(f)
    else:
        printer.warn("无文件!")

def get_files(fDir,suf):
    result = []
    for _,_,files in os.walk(fDir):
        for f in files:
            name,suffix = os.path.splitext(f)
            if suf:
                if suffix == suf:
                    result.append(name)
            else:
                result.append(f)
    return result

def show_flies():
    printer.info("分割的文件如下: ")
    dfiles = get_files(DFILE,"")
    if dfiles:
        for d in dfiles:
            printer.plus(d)
    else:
        printer.warn("无文件!")
    return dfiles

def check_path(fp):
    if os.path.isfile(fp):
        return True
    else:
        return False

def get_file_size(fp):
    return os.path.getsize(fp)

def read_file(fp,size):
    with open(fp,'rb') as fr:
        c = fr.read(size)
        if c:
            ls = [c[i:i+1] for i in range(len(c))]
            for i in range(len(ls)):
                yield ls[i]

def read_mem_file(c):
    ls = [c[i:i+1] for i in range(len(c))]
    for i in range(len(ls)):
        yield ls[i]
def read_mem_str(c):
    ls = [c[i:i+1] for i in range(len(c))]
    return ls
def check_ascii(ct):
    result = []
    for c in range(len(ct)):
        t = ct[c:c+1]
        if ord(t)<127 and ord(t)>=32:
            result.append(True)
        else:
            result.append(False)
    return all(result)

def vali_char(b):
    if check_ascii(b):
        return b
    else:
        return b'.'
def show_mem_hex(mc):
    memAddr = 0
    content = b""
    for bstr in read_mem_file(mc):
        content = content + vali_char(bstr)
        if memAddr%16 == 0:
            print(format(memAddr,"06X"),end="" )
            print("   ",end="")
            print(binascii.hexlify(bstr).decode(encoding='utf-8', errors='strict'),end="")
            print(" ",end="")
        elif memAddr%16 == 15:
            print(binascii.hexlify(bstr).decode(encoding='utf-8', errors='strict'),end="")
            print("   ",end="")
            print(content.decode(encoding='utf-8', errors='strict'),end="")
            content = b""
            print("")
        else:
            print(binascii.hexlify(bstr).decode(encoding='utf-8', errors='strict'),end="")
            print(" ",end="")
        memAddr += 1

def find_str(files:list,posstr):
    content = b''
    retfalse = ''
    if files:
        for f in files:
            fsize = get_file_size(f)
            for b in read_file(f,fsize):
                content = content + vali_char(b)
                cstr = content.decode(encoding='utf-8', errors='strict')
                if cstr.find(posstr) >=0:
                    return f
    return retfalse

def read_hexfile(hfile):
    memAddr = 0
    content = b""
    fsize = get_file_size(hfile)
    for b in read_file(hfile,fsize):
        content = content + vali_char(b)
        #show_hex(memAddr,content,b)
        memAddr += 1
def position_str(pos):
    global MFILES
    result = ""
    content = b""
    for k,v in MFILES.items():
        blist = read_mem_str(v)
        for b in blist:
            content = content + vali_char(b)
        cstr = content.decode(encoding='utf-8', errors='strict')
        clen = len(cstr) - 1
        if cstr.find(pos) >=0:
            idex = cstr.find(pos)
            result = k
            if clen - idex > 100 :
                printer.info(cstr[idex:idex + 50])
            else:                 
                printer.info(cstr[idex-1:-1])
            break
        content = b""
    if result:
        printer.plus(result)
        #show_mem_hex(MFILES[result])
        MFILES = {}
    else:
        printer.warn("未找到内容!")
def show_menu():
    printer.info("菜单: ")
    printer.plus("1. 查看文件")
    printer.plus("2. 定位内容")
def execute(fp):
    try:
        global MFILES
        fp = input("请输入文件路径: ")
        cf = check_path(fp)
        if cf:
            fsize = get_file_size(fp)
            printer.info("当前文件大小: " + str(fsize) + " 字节")
            chunk = input("请输入要分割的大小: ")
            chunk = int(chunk)
            show_mem_files(fp,chunk)
            show_menu()
            choice = input("请输入选项: ")
            if choice.strip() == "1":
                while MFILES:
                    cfile = input("请输入要查看的文件名[q:退出]:")
                    cfile = cfile.strip()
                    if cfile == "q":
                        MFILES = {}
                        break
                    for k,v in MFILES.items():
                        if k == cfile:
                            show_mem_hex(v)
                    print(" ")
                else:
                    printer.warn("无文件!")
            elif choice == "2":
                fstr = input("请输入要定位的字符串: ")
                fstr = fstr.strip()
                position_str(fstr)
                print(" ")
            else:
                printer.warn("参数无效!")
    except Exception as e:
        printer.warn("运行出现异常!")
        traceback.print_exc()


